#include "skyplane.h"

skyplane::skyplane(void)
{
	texture1 = new Texture("textures/skypanorama.bmp");
	GenerateDome(10.0, 100.0, 20, 1.0, 1.0);
}

skyplane::~skyplane(void)
{
	delete texture1;
}

void skyplane::draw()
{
	glPushAttrib(GL_ENABLE_BIT);
	glShadeModel(GL_SMOOTH);
	glEnable( GL_AUTO_NORMAL );
	glEnable( GL_NORMALIZE );
	glEnable( GL_TEXTURE_2D );

	texture1->bind();

	glColor3f(1.0,1.0,1.0);

	//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

	glBegin(GL_TRIANGLES);
	// Draw plane

	for(int i=0; i < NumIndices; i++)
	{
		glTexCoord2f(vertices[Indices[i]].u, vertices[Indices[i]].v);
		glVertex3f(vertices[Indices[i]].x, vertices[Indices[i]].y, vertices[Indices[i]].z);
	}

	glEnd();

	glPopAttrib();
}

void skyplane::GenerateDome(float pRadius, float aRadius, int Divisions, float hTile, float vTile)
{
	std::cout << "You called the GenerateDome function!\n";
	int divs = Divisions;

	// make sure the divisions are within an acceptable range
	if (divs < 1) divs = 1;
	if (divs > 256) divs = 256;

	// Calculate the number of vertices and indices needed
	NumOfVertices = (divs + 1) * (divs + 1);
	NumIndices = divs * divs * 2 * 3;

	// Allocate memory for the vertices
	vertices = new VERTEX[NumOfVertices];
	memset(vertices, 0, sizeof(VERTEX));
	float PlaneSize = 2.0f * (float)sqrt((aRadius*aRadius-pRadius*pRadius));
	float PlaneDelta = PlaneSize/(float)Divisions;
	float TextureDelta = 2.0f/(float)Divisions;

	// variables used during the dome's generation
	float x_dist = 0.0f;
	float z_dist = 0.0f;
	float x_height = 0.0f;
	float z_height = 0.0f;
	float height = 0.0f;
	VERTEX SV; // temporary vertex

	int count = 0;

	for (int i=0; i <= Divisions; i++)
	{
		for (int j=0; j <= Divisions; j++)
		{
			x_dist = (-0.5f * PlaneSize) + ((float)j*PlaneDelta);
			z_dist = (-0.5f * PlaneSize) + ((float)i*PlaneDelta);
			x_height = (x_dist * x_dist) / aRadius;
			z_height = (z_dist * z_dist) / aRadius;
			height = x_height + z_height;
			SV.x = x_dist;
			SV.y = 0.0f - height;
			SV.z = z_dist;

			// Calculate Texture Coordinates
			SV.u = hTile * ((float)j * TextureDelta*0.5f);
			SV.v = vTile * (1.0f - (float)i * TextureDelta*0.5f);
			vertices[i*(Divisions+1)+j] = SV;
		}
	}

	// Done calculating vertices, calculate the indices
	int index = 0;
	Indices = new WORD[NumIndices];
	for (int i=0; i < Divisions; i++)
	{
		for (int j=0; j < Divisions; j++)
		{
			int startvert = (i*(Divisions+1) + j);
			// triangle 1
			Indices[index++] = startvert;
			Indices[index++] = startvert+1;
			Indices[index++] = startvert+Divisions+1;
			// triangle 2
			Indices[index++] = startvert+1;
			Indices[index++] = startvert+Divisions+2;
			Indices[index++] = startvert+Divisions+1;
		}
	}
	verticesToFile(vertices, "vertexCoordinatsSkyplane.txt");
	textureCoordinatsToFile(vertices, "textureCoordinatsSkyplane.txt");
	indicesToFile("indicesSkypoane.txt");
}

void skyplane::verticesToFile(VERTEX * vertices, char * filename){
	std::ofstream file;
	file.open(filename);

	file << "NumOfVertices = " << NumOfVertices << "\n";

	int i;
	for(i=0; i<NumOfVertices; i++){
		file << "Vertex " << i << " = {" << vertices[i].x << ", " << vertices[i].y << ", " << vertices[i].z << "}\n";
	}
	file.close();
}

void skyplane::textureCoordinatsToFile(VERTEX * vertices, char * filename){
	std::ofstream file;
	file.open(filename);
	int i;
	float minU = 1.0, maxU = 0.0;
	float minV = 1.0, maxV = 0.0;
	
	for(i=0; i<NumOfVertices; i++){
		if(minU > vertices[i].u)
			minU = vertices[i].u;
		if(maxU < vertices[i].u)
			maxU = vertices[i].u;
		if(minV > vertices[i].v)
			minV = vertices[i].v;
		if(maxV < vertices[i].v)	
			maxV = vertices[i].v;
		file << "Vertex " << i << " = {" << vertices[i].u <<  ", " 
		<< vertices[i].v << "}\n";
	}
	file << "status:\n" << "minU=" << minU << " | maxU=" << maxU
					 << "\nminV=" << minV << " | maxV=" << maxV << "\n";
	file.close();
}

void skyplane::indicesToFile(char * filename){

	std::ofstream file;
	file.open(filename);

	for(int i = 0; i < NumIndices; i++){
		file << "Index : " << i << " = " << Indices[i] << "\n";
	}
}